package com.jmu.posms.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmu.posms.common.Result;
import com.jmu.posms.dto.AddUserInputDto;
import com.jmu.posms.dto.UpdateUserDto;
import com.jmu.posms.dto.UserLoginDto;
import com.jmu.posms.dto.UserRoleDto;
import com.jmu.posms.exception.ServiceException;
import com.jmu.posms.pojo.Role;
import com.jmu.posms.pojo.User;
import com.jmu.posms.service.RoleService;
import com.jmu.posms.service.UserService;
import com.jmu.posms.util.CryptoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.jws.soap.SOAPBinding;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    UserService userService;
    @Resource
    RoleService roleService;

    /**
     * 用户注册
     * @param addUserInputDto
     * @return
     */
    @PostMapping("/register")
    public Result register(@RequestBody AddUserInputDto addUserInputDto) {
        userService.register(addUserInputDto);

        return Result.success(null,"注册成功");
    }

    /**
     * 用户登录
     * @param loginDto
     * @param request
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody UserLoginDto loginDto, HttpServletRequest request){
        Subject subject = SecurityUtils.getSubject();

        subject.getSession().getId();

        log.info(loginDto.toString());

        String userName = loginDto.getUserName();
        String password = loginDto.getPassword();
        String host = request.getRemoteAddr();

        UsernamePasswordToken token =new UsernamePasswordToken(userName,password,host);

        if("on".equals(loginDto.getRemember())){
//            token.setRememberMe(true);
        }

        try {
            subject.login(token);
            // 登录成功
            User user = (User) subject.getPrincipal();
            log.info("用户：" + user.getUserName() + "登录成功");
            //查询用户权限信息
//            PermissionOutputDto dto = permissionService.findRouterPermissions(user.getId());

//            return Result.success(new UserLoginOutputDto(user,dto));
            return Result.success(user,"登录成功");
        } catch (UnknownAccountException e) {
            //账号不存在
            throw new ServiceException("600","用户名或密码错误");
        }catch (DisabledAccountException e){
            //账号异常
            throw new ServiceException("600","账号异常");
        }
        catch (AuthenticationException e){
            //密码错误
            throw new ServiceException("600","用户名或密码错误");
        }
    }

    @PostMapping("/logout")
    public Result logout(){
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.logout();
        } catch (Exception e) {
            throw new ServiceException("600", "登出失败");
        }
        return Result.success("登出成功", null);
    }

    /**
     * 根据用户id获取单个用户
     * @return
     */
    @GetMapping("/get/{id}")
    public Result getByuserName(@PathVariable String id){
        User user = userService.getById(id);
        return Result.success(user);
    }

    @GetMapping("/get/role/{id}")
    public Result getUserRole(@PathVariable String id){
        Role role = roleService.getById(id);
        return Result.success(role.getRoleName());
    }

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @param name 根据名称模糊查询
     * @return
     */
    @GetMapping("/get/page")
    public Result page(Integer page,Integer pageSize,String name){
        //构造分页构造器
        Page pageInfo = new Page(page,pageSize);

        //构造条件构造器
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
        //添加过滤条件  like ---> %name%
        queryWrapper.like(StringUtils.isNotEmpty(name),User::getUserName,name);
        //添加排序条件 , 根据注册的日期排序
        queryWrapper.orderByDesc(User::getModifyDate);

        //执行查询
        try{
            userService.page(pageInfo, queryWrapper);
        }catch (Exception e){
            throw new ServiceException("600","分页查询失败");
        }
        return Result.success(pageInfo,"查询成功");
    }

    /**
     * 根据传入的id等信息 更新用户信息  ， ID一定要
     * 也可以只传id 和  password  用来更改密码
     * @param user
     * @return
     */
    @PutMapping("/update")
    public Result update(@RequestBody UpdateUserDto user){
        log.info(user.toString());

        //如果要修改密码 ，  密码是需要加密的
        if (user.getPassword()!=null) {
            //获取数据库存的创建日期，因为是用日期作为盐值来加密的 ， 因此修改密码的时候需要重新加密！
            String salt = userService.getById(user.getId()).getModifyDate();
            //log.info("修改密码时从数据库获取的盐值-------->"+salt);
            String password = CryptoUtil.md5Encode(user.getPassword(),salt);
            user.setPassword(password);
            //log.info("加密后的密码--------->"+user.getPassword());
        }

        User userupdate = new User();
        BeanUtils.copyProperties(user,userupdate);
        try{
            userService.updateById(userupdate);
        }catch (Exception e){
            throw new ServiceException("600","修改信息失败");
        }
        return Result.success(null,"修改成功");
    }

    /**
     * 根据id删除单个用户
     * @param id 用户id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable String id){
        try {
            userService.removeById(id);
        }catch (Exception e){
            throw new ServiceException("600","删除失败");
        }
        return Result.success(null,"删除成功");
    }

    /**
     * 批量删除用户 ， 必须传的json [{},{}]  只需要有id就行  两个以上，不然会报错  不存在该用户不会报错
     * [
     *
     *     "1"
     *     "1531932037099786242"
     *      ......
     * ]
     * @param users
     * @return
     */
    @DeleteMapping("/delete")
    public Result delete(@RequestBody List<String> users) {
        log.info(users.toString());
        try {
            userService.removeBatchByIds(users);
        } catch (Exception e) {
            throw new ServiceException("600", "删除失败");
        }
        return Result.success( null,"删除成功");
    }

    @GetMapping("/get/now")
    public Result getNowUser(){
        Subject subject = SecurityUtils.getSubject();
        User nowUser = (User) subject.getPrincipal();
        if(nowUser == null){
            throw new ServiceException("401","请登录");
        }
        String roleName = roleService.getById(nowUser.getRoleId()).getRoleName();
        UserRoleDto user = new UserRoleDto();
        user.setName(nowUser.getUserName());
        user.setRole(roleName);
        user.setId(nowUser.getId());
        user.setEmail(nowUser.getEmail());
        user.setTelephone(nowUser.getTelephone());
        user.setDescription(nowUser.getDescription());
        return Result.success(user);
    }
}
